﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using Newtonsoft.Json;
using UnityEditor.Build.Reporting;
using UnityEditor.Callbacks;
using cframework;

#if UNITY_IOS 
//using ChillyRoom.UnityEditor.iOS.Xcode;
using UnityEditor.iOS.Xcode;
#endif

class AndroidKeyStoreInfo
{
    public string keystorePass;
    public string keyaliasName;
    public string keyaliasPass;
}


class BuildAppInfo
{
    public string app_name;
    public string platform;
    public string bundle_identifier;
    public string publish_type = "dev";
	//public string version;
	public int version_number;
	public ulong build_time;
}


public class BuildTool
{
    public static void Build(string outputPath)
    {

        switch (EditorUserBuildSettings.activeBuildTarget)
        {
            case BuildTarget.Android:
                {
                    BuildAndroidProject(outputPath);
                }
                break;
            case BuildTarget.iOS:
                {
                    BuildIOS_Project(outputPath);
                }
                break;
            case BuildTarget.WebGL:
                {
                    BuildWebGL(outputPath);
                }
                break;
            case BuildTarget.StandaloneWindows:
                {
                    BuildStandalone(outputPath, 4);
                }
                break;
            case BuildTarget.StandaloneWindows64:
                {
                    BuildStandalone(outputPath, 8);
                }
                break;
            case BuildTarget.StandaloneOSX:
            case BuildTarget.StandaloneOSXIntel:
            case BuildTarget.StandaloneOSXIntel64:
                {
                    BuildStandalone(outputPath, 0);
                }
                break;
        }
    }

    public static void BuildStandalone(string outputPath, int intPtrSize)
    {
        Build2(BuildTargetGroup.Standalone, intPtrSize, outputPath, BuildOptions.None);
    }

    public static void BuildWebGL(string outputPath)
    {
        Build2(BuildTargetGroup.WebGL, 0, outputPath, BuildOptions.None);
    }


    public static void BuildAndroidProject(string outputPath)
    {
        Build2(BuildTargetGroup.Android, 0, outputPath, BuildOptions.None);
    }


    public static void BuildIOS_Project(string outputPath)
    {
        Build2(BuildTargetGroup.iOS, 0, outputPath, BuildOptions.None);
    }

    public static BuildTarget GetTarget(BuildTargetGroup targetGroup, int intPtrSize)
    {
        BuildTarget target = BuildTarget.NoTarget;
        if (targetGroup == BuildTargetGroup.Android)
        {
            target = BuildTarget.Android;
        }
        else if (targetGroup == BuildTargetGroup.iOS)
        {
            target = BuildTarget.iOS;
        }
        else if (targetGroup == BuildTargetGroup.WebGL)
        {
            target = BuildTarget.WebGL;
        }
        else if (targetGroup == BuildTargetGroup.Standalone)
        {
            if (Application.platform == RuntimePlatform.OSXEditor)
            {
                target = BuildTarget.StandaloneOSX;
            }
            else if (Application.platform == RuntimePlatform.WindowsEditor)
            {
                if(intPtrSize == 4)
                {
                    target = BuildTarget.StandaloneWindows;
                }
                else
                {
                    target = BuildTarget.StandaloneWindows64;
                }
            }
        }

        return target;
    }


    public static void Build2(BuildTargetGroup targetGroup, int intPtrSize, string dir, BuildOptions opt)
    {
        BuildTarget target = GetTarget(targetGroup, intPtrSize);

        if (EditorUserBuildSettings.selectedBuildTargetGroup != targetGroup)
        {
            EditorUserBuildSettings.SwitchActiveBuildTarget(targetGroup, target);
            EditorUserBuildSettings.selectedBuildTargetGroup = targetGroup;
        }

        if(target  == BuildTarget.Android)
        {
            EditorUserBuildSettings.androidBuildSystem = AndroidBuildSystem.Gradle;
        }

		if (dir.Contains ("."))
		{
			string realDir = System.IO.Path.GetDirectoryName (dir);
			if (System.IO.Directory.Exists(realDir))
			{
				System.IO.Directory.Delete(realDir, true);
			}
		}

        if (System.IO.Directory.Exists(dir))
        {
            System.IO.Directory.Delete(dir, true);
        }

        string outputDir = dir;
        if(target == BuildTarget.StandaloneWindows64 || target == BuildTarget.StandaloneWindows)
        {
            System.IO.Directory.CreateDirectory(outputDir);
            outputDir += "/" + PlayerSettings.productName + ".exe";
        }

        if(target == BuildTarget.StandaloneOSX)
        {
            if(!dir.EndsWith(".app"))
            {
                dir += ".app";
            }
        }
        

        string[] LevelArray = GetScenePaths();

        if (EditorUserBuildSettings.development)
        {
            opt |= BuildOptions.Development;
        }

        Debug.Log("build with options: " + opt);


        BuildReport errorMsg = null;


        Debug.Log("BuildPipeline.BuildPlayer begin:  target:" + target + "   outputDir:" + outputDir);
        errorMsg = BuildPipeline.BuildPlayer(LevelArray, outputDir, target, opt);
        Debug.Log("BuildPipeline.BuildPlayer end");


        if (errorMsg != null && errorMsg.summary.result == BuildResult.Succeeded)
        {
            if(targetGroup == BuildTargetGroup.Standalone)
            {
                if(target == BuildTarget.StandaloneWindows64 || target == BuildTarget.StandaloneWindows)
                {
                    string[] paths = System.IO.Directory.GetDirectories(dir, "*_BackUpThisFolder_ButDontShipItWithYourGame", System.IO.SearchOption.TopDirectoryOnly);

                    if(paths.Length > 0)
                    {
                        string path = paths[0];
                        string dirPath = System.IO.Path.GetDirectoryName(path);
                        dirPath = System.IO.Path.GetDirectoryName(dirPath);
                        string fileName = System.IO.Path.GetFileName(path);

                        CommonUtil.Move(path, dirPath + "/" + fileName);

                        //string[] dllFilePaths = System.IO.Directory.GetFiles(dirPath + "/" + fileName, "*.dll", System.IO.SearchOption.AllDirectories);

                        //string log = "dll:\n";
                        //System.Array.Sort(dllFilePaths);
                        //foreach(var a in dllFilePaths)
                        //{
                        //    log += a + "\n";
                        //}

                        //Debug.Log(log);
                    }   

                    
                }
            }

            if(target == BuildTarget.StandaloneWindows64 || target == BuildTarget.StandaloneWindows || target == BuildTarget.WebGL)
            {
                HotUpdateAppInfo appInfo = AppManager.GetAppInfo();
                BuildAppInfo buildAppInfo = new BuildAppInfo();
                buildAppInfo.app_name = appInfo.app_name;
                buildAppInfo.platform = EditorCommonTool.getPlatform().ToString();
                buildAppInfo.bundle_identifier = PlayerSettings.GetApplicationIdentifier(targetGroup);
                buildAppInfo.publish_type = AppManager.GetAppInfo().publish_type;
                buildAppInfo.version_number = AppManager.GetAppInfo().hotupdate_version;
                buildAppInfo.build_time = AppManager.GetAppInfo().timestamp;

                CommonUtil.ObjectToJsonFile(buildAppInfo, dir + "/" + "version_info.txt");
            }

            

            Debug.Log("build output dir: " + dir);
        }
        else
        {
            string log = "";
            for(int i = errorMsg.steps.Length - 1; i >= 0; i--)
            {
                BuildStep step = errorMsg.steps[i];

                log += step.name + ":\n";
                var msgs = step.messages;
                for(int j = 0; j < msgs.Length; j++)
                {
                        log += "\t" +msgs[j].type + " | " + msgs[j].content + "\n";
                }
            }

            throw new System.Exception("build error msg: " + log + "\n");
        }
    }

    public static string[] GetScenePaths()
    {
        List<string> arrScenes = new List<string>();

        for (int i = 0; i < EditorBuildSettings.scenes.Length; i++)
        {
            EditorBuildSettingsScene scene = EditorBuildSettings.scenes[i];
            if (scene.enabled && System.IO.File.Exists(scene.path))
            {
                arrScenes.Add(scene.path);
            }
        }

        string[] scenes = arrScenes.ToArray();
        return scenes;
    }

//    [PostProcessBuildAttribute(1)]
//    public static void OnPostprocessBuild(BuildTarget buildTarget, string outputProjectPath)  
//    {
//#if UNITY_IOS
//        if (buildTarget == BuildTarget.iOS)
//        {
//            // if(SwitchConfig.isEnableHotUpdate)
//            {
//                string il2cppFilePath = System.IO.Path.Combine(outputProjectPath, "Libraries/libil2cpp.a");
//                if(CommonUtil.Exists(il2cppFilePath))
//                {
//#if !DISABLE_HYBRIDCLR
//                    string srcPath = System.IO.Path.Combine(HybridCLR.Editor.SettingsUtil.HybridCLRDataDir, "iOSBuild/build/libil2cpp.a");
//                    if(CommonUtil.Exists(srcPath))
//                    {
//                        CommonUtil.Delete(il2cppFilePath);
//                        CommonUtil.Copy(srcPath, il2cppFilePath);
//                    }
//#endif
//                }
//            }
//        }
//#endif
//    }
    //    #endif
}
